﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;

public class UITextTimer : MonoBehaviour
{

    public Text textLabel;
    private string finishLabelString = "";

    public enum TIMER_TYPE
    {
        INTER,
        PERCENTAGE,
        TIMER_MINUTE,
        TIMER_SECOND,
        TIMER_MINUTE_SECOND,
        TIMER_MS,
    }

    [Tooltip("tooltip: 显示时间类型,NUMBER = 普通，TIMER_MINUTE =显示到分钟，TIMER_SECOND=显示到秒钟")]
    public TIMER_TYPE timeType = TIMER_TYPE.TIMER_SECOND;

    [Tooltip("用于搜索的标签，可以被BhvTextTimer 搜索到(未实装)")]
    public string timerTag = "";


    public float timer = 0;
    public float targetTimer = 9.9f;
    [HideInInspector] public bool isPause = true;
    public UnityEvent finishEvents;
    public bool activeAtStart = false;
    static Dictionary<string, UITextTimer> _timer_dics = new Dictionary<string, UITextTimer>();

    private void Awake()
    {


        if (textLabel == null)
        {
            textLabel = GetComponent<Text>();
        }
        if (activeAtStart)
        {
            StartTimer(this.targetTimer, this.finishLabelString, "");
        }
    }

    /// <summary>
    /// 查找拥有对应tag 的TextTimer 组件
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="tag"></param>
    /// <returns></returns>
    static public UITextTimer Find(GameObject obj, string tag)
    {
        var comps = obj.GetComponentsInChildren<UITextTimer>();
        for (int i = 0; i < comps.Length; i++)
        {
            var comp = comps[i];
            if (comp.timerTag == tag)
            {
                return comp;
            }
        }

        return null;
    }


    /// <summary>
    /// 开始计时器
    /// </summary>
    /// <param name="time"> 计时单位 秒</param>
    /// <param name="finishText">完成时候显示的 字符</param>
    /// <param name="tag">标记计时器标签</param>
    public void StartTimer(float timeSecond, string finishText = "", string tag = "")
    {
        if (tag != "") this.timerTag = tag;
        if (finishText != "") finishLabelString = finishText;

        targetTimer = timeSecond;
        timer = targetTimer;
        this.isPause = false;
    }

    public void StopTimer(bool forceTrigger = false)
    {
        isPause = true;
        if (forceTrigger) OnFinishTimer();
    }

    public float getPercentage()
    {
        float percentage = 1 - (this.timer / this.targetTimer);
        percentage = Mathf.Clamp(percentage, 0, 1.0f);
        return percentage;
    }

    private void Update()
    {
        if (isPause) return;
        timer -= Time.deltaTime;
        if (timer <= 0)
        {
            isPause = true;
            OnFinishTimer();
        }
        else
        {
            UpdateText();
        }

    }

    private void OnFinishTimer()
    {
        finishEvents.Invoke();
    }

    private void UpdateText()
    {
        if (textLabel == null) return;
        var str = "";
        switch (timeType)
        {
            case TIMER_TYPE.INTER:
                str = Mathf.RoundToInt(this.timer) + "";
                break;
            case TIMER_TYPE.PERCENTAGE:
                str = Mathf.Floor(this.getPercentage() * 100) + "%";
                break;
            case TIMER_TYPE.TIMER_MINUTE:
                str = UITextTimer.ParseTimeStamp(this.timer, "min");
                break;
            case TIMER_TYPE.TIMER_SECOND:
                str = UITextTimer.ParseTimeStamp(this.timer, "sec");
                break;
            case TIMER_TYPE.TIMER_MINUTE_SECOND:
                str = UITextTimer.ParseTimeStamp(this.timer, "min-sec");
                break;
            case TIMER_TYPE.TIMER_MS:
                str = UITextTimer.ParseTimeStamp(this.timer, "ms");
                break;
            default:
                break;
        }

        textLabel.text = str;

    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="timeStamp"></param>
    /// <param name="timerUnit"> 'int'| 'ms' | 'sec' | 'min' </param>
    /// <returns></returns>
    static string ParseTimeStamp(float timeStamp, string timerUnit = "sec")
    {
        var time = timeStamp * 1000;
        string result = "";

        float ms = Mathf.Floor(time % 1000);
        float sec = Mathf.Floor((time / 1000) % 60);
        float min = Mathf.Floor((time / 1000 / 60) % 60);
        float hour = Mathf.Floor((time / 1000 / 60 / 60) % 24);
        string sMS, sSEC, sMIN, sHOUr;

        //补位
        sMS = ((ms < 100) ? "0" : "") + ms;
        sSEC = ((sec < 10) ? "0" : "") + sec;
        sMIN = ((min < 10) ? "0" : "") + min;
        sHOUr = ((hour < 10) ? "0" : "") + hour;

        switch (timerUnit)
        {
            case "ms":
                result = sHOUr + ":" + sMIN + ":" + sSEC + ":" + sMS;
                break;
            case "min":
                result = sHOUr + ":" + sMIN;
                break;
            case "sec":
                result = sHOUr + ":" + sMIN + ":" + sSEC;
                break;
            case "min-sec":
                result = (min + hour * 60) + ":" + sSEC;
                break;
            default:
                result = sHOUr + ":" + sMIN + ":" + sSEC;
                break;
        }

        return result;
    }

}
